iT邦幫忙

2022 iThome 鐵人賽

DAY 8
0

當無法在時間內完成 View 的繪製,使用者就會感到 UI 的延遲,實際上 View 的繪製做了哪些事情?下圖左邊是我們的 Layout 編排,最外層有一個 LinearLayout,裡面放了2 個 Button。右邊則是實際在手機上的畫面。在這個 LinearLayout 我們只是告訴他用垂直排序,沒有對裡面的元件指定大小,那麼 Android 要怎麼知道在把這些 UI 繪製出來時,應該畫在什麼位置及大小呢?

layout

我們就來看 Android 是怎麼從 Layout 的編排,繪製到手機的畫面上。

View 的繪製有3個步驟:

  1. Measure:測量View在螢幕上的寬高
  2. Layout:測量顯示在螢幕上的位置
  3. Draw:繪出View

Measure

View 繪製的第一個步驟是 Measure 測量。為什麼需要測量呢?因為我們並不是在每個地方都會直接指定 View 的大小。例如下式程式碼的 Button,我們把寬度設定match_parent 為與父元件一樣寬,將高度設定為wrap_content依內容決定高度。所以 Button 的實際寬高需要同時參考它的父容器來決定。

<Button
    android:layout_width="match_parent"
    android:layout_height="wrap_content" />

所以上面的程式碼並不是完整的,Button 一定會在某個父容器裡。我們將其改成的下方程式碼,放 2 個 Button 在 LinearLayout 裡。LinearLayout 的元件會以垂直或水平的方式來排序,所以 LinearLayout 的大小會被裡面的 Button 所影響,Button 的大小也會被父元件所限制。

<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical">
    <Button
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />
    <Button
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />
</LinearLayout>

在這樣的情況下,要測量實際的寬高就更複雜了。為此,Android 提供了 MeasureSpec 來讓父容器與子元件進行溝通,由父容器提供給子元件做為設定自身大小的參考:

MeasureSpec 的 三種測量模式:

UNSPECIFIED :父容器不對子元件加以限制,子元件可以長到想要的大小。
EXACTLY:父容器為子元件指定大小。
AT_MOST:父容器為子元件指定最大的大小。

所以當子 View 收到父 View 傳遞的 MeasureSpec,就知道父 View 希望子 View 如何設定大小。Android 系統就是透過這種方式是測量出實際出繪製的寬高。

到這邊應該就會有感覺到如果 Layout 的層級很深,就會增加測量的複雜度。

Layout

完成了測量大小,也就是 View 的寬高。接著要算出 View 的位置,也就是 View 要放在哪裡。View的位置一樣會與子 View、父 View 的大小與寬度有關。位置的測量比較簡單,只要透過 onLayout(boolean changed, int left, int top, int right, int bottom)來完成定位。

Draw

在 View 的大小與位置都確定後,終於可以把 Layout 給畫出來了,透過 Canvas 來實現繪製 UI。

繪製的步驟:

  1. 繪製 Background
  2. 繪製 View
  3. 繪製 Child
  4. 繪製 Scrollbar

其實我們一般在做 Layout 的編排,是不需要自行處理這3個步驟的,除非你要自已寫 Customview 。我們只是透過了解 View 繪製的過程來發現它會如何影響效能。當 Layout 的階層越多、元件越多,繪製也就越耗時。如果 Layout 過於複雜無法在 60fps 的情況,16 毫秒內完成這3個步驟 Measure、Layout、Draw,就會有 Janky frame 的產生,而使用者就可能感到延遲。下一篇我們就接著來先介紹 Layout 編排是如何影響效能的。


上一篇
UI 的效能優化
下一篇
優化版面配置
系列文
Android app 效能優化30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言